package com.ys.service.storage.impl;

import com.ys.config.MenuId;
import com.ys.entity.finance.TcwExpenseSettleReturnItem;
import com.ys.entity.finance.TcwExpenseSettleReturnUsed;
import com.ys.entity.purchase.TcgPurchaseByOrder;
import com.ys.entity.purchase.TcgPurchaseByOrderSon;
import com.ys.entity.storage.*;
import com.ys.enume.finance.TcwExpenseSettleReturnUsedEnum;
import com.ys.enume.purchase.TcgOfflinePurchaseInStorageEnum;
import com.ys.enume.storage.TccOnlineAssembleErrorEnum;
import com.ys.enume.storage.TccOnlinePurchaseReturnUsedEnum;
import com.ys.mapper.finance.FinanceMapper;
import com.ys.mapper.finance.TcwExpenseSettleReturnUsedMapper;
import com.ys.mapper.storage.StorageMapper;
import com.ys.mapper.storage.TccOnlineAssembleErrorItemMapper;
import com.ys.mapper.storage.TccOnlineAssembleErrorMapper;
import com.ys.mapper.storage.TccOnlinePurchaseReturnUsedMapper;
import com.ys.service.purchase.TcgOfflinePurchaseInStorageService;
import com.ys.service.storage.TccOnlineAssembleErrorService;
import com.ys.service.sys.CommonApiService;
import com.ys.util.CheckUtil;
import com.ys.vo.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 线上组装报错单
 */
@Service("tccOnlineAssembleErrorService")
public class TccOnlineAssembleErrorServiceImpl implements TccOnlineAssembleErrorService {
	private static final Logger logger = LoggerFactory.getLogger(TccOnlineAssembleErrorServiceImpl.class);

	@Autowired
	private TccOnlineAssembleErrorMapper tccOnlineAssembleErrorMapper;

	@Autowired
	private TccOnlineAssembleErrorItemMapper tccOnlineAssembleErrorItemMapper;

	@Autowired
	private CheckUtil checkUtil;

	@Autowired
	private FinanceMapper financeMapper;

	@Autowired
	private StorageMapper storageMapper;

	@Autowired
	private CommonApiService<TccOnlineAssembleError> commonApiService;

	private Long menuId = MenuId.TCC_OnlineAssembleError;

	//入库单
	@Autowired
	private TcgOfflinePurchaseInStorageService tcgOfflinePurchaseInStorageService;

	@Autowired
	private TcwExpenseSettleReturnUsedMapper tcwExpenseSettleReturnUsedMapper;

	@Autowired
	private TccOnlinePurchaseReturnUsedMapper tccOnlinePurchaseReturnUsedMapper;

	/**
	 * 新增线上组装报错单
	 * @param assembleId 线上组装单表id
	 * @param itemList 子列表信息
	 */
	@Override
	public R add(Long assembleId,  List<TccOnlineAssembleErrorItemByAdd> itemList) throws Exception{
		logger.info("新增传参:"+assembleId+";"+itemList);

		Map<String, List<TccOnlineAssembleErrorItemByAdd>> groupsByOrderBid = itemList.stream().collect(Collectors.groupingBy(e->e.getOrderBid()));

		//遍历，填入去重的信息
		groupsByOrderBid.forEach((orderBid, itemListGroupByOrderBid) -> {
			TccOnlineAssembleError entity =new TccOnlineAssembleError();
			entity.setStatus(1);//状态
			//获取单号
			String bid = null;
			try {
				bid = commonApiService.getCommonNextBid(menuId);
			} catch (Exception e) {
				e.printStackTrace();
			}
			//单号
			entity.setBid(bid);
			entity.setAssembleId(assembleId);//线上组装单表id

			entity.setPurchaseOrderBid(orderBid);

			//总缺失金额
			BigDecimal lostAmountTotal = BigDecimal.ZERO;
			for(TccOnlineAssembleErrorItemByAdd item:itemListGroupByOrderBid){
				//子件缺失金额 = 子件采购单价 * 子件缺失数量
				lostAmountTotal = lostAmountTotal.add(item.getSubAmount().multiply(new BigDecimal(item.getSubAssembleLostNum())));
			}
			//查看是否是正常范围；判断条件：子件缺失金额，之和≤5元
			if(lostAmountTotal.compareTo(new BigDecimal(5))<=0){
				entity.setHandleStatus(TccOnlineAssembleErrorEnum.HandleStatus.NORMAL.value);//报错状态 :正常范围
				entity.setErrorCause("缺失金额不足5元");
			}else {
				entity.setHandleStatus(TccOnlineAssembleErrorEnum.HandleStatus.DID_NOT_DO.value);//报错状态 :待处理
			}

			//新增母表信息
			tccOnlineAssembleErrorMapper.insert(entity);

			//新增子表信息
			for(TccOnlineAssembleErrorItemByAdd item:itemListGroupByOrderBid){
				TccOnlineAssembleErrorItem tccOnlineAssembleErrorItem = new TccOnlineAssembleErrorItem();
				tccOnlineAssembleErrorItem.setPbid(bid);
				tccOnlineAssembleErrorItem.setStatus(1);
				tccOnlineAssembleErrorItem.setSubAssembleLostNum(item.getSubAssembleLostNum());//子件缺失数量
				tccOnlineAssembleErrorItem.setSubCode(item.getSubCode());//子件编码
				tccOnlineAssembleErrorItem.setAssembleItemId(item.getAssembleItemId());//线上组装单子件明细表id
				tccOnlineAssembleErrorItem.setSubAmount(item.getSubAmount());//子件采购单价
				tccOnlineAssembleErrorItemMapper.insert(tccOnlineAssembleErrorItem);
			}

		});
		return R.ok();
	}


	//处理之前判断
	public String handleBeforeCheck(String purchaseOrderBid,List<TccOnlineAssembleError> assembleErrorList){
		StringBuffer errorMsg = new StringBuffer();
		if(assembleErrorList!=null && assembleErrorList.size()>0){
			for(TccOnlineAssembleError item:assembleErrorList){
				if(item.getHandleStatus() != TccOnlineAssembleErrorEnum.HandleStatus.DID_NOT_DO.value){
					errorMsg = new StringBuffer()
							.append("该订单：")
							.append(purchaseOrderBid)
							.append("不是处于待处理状态")
					;
				}
			}
			return errorMsg.toString();
		}else {
			return "未查询到对应的线上组装报错单信息";
		}
	}

	/**
	 * 不处理
	 * @param purchaseOrderBid 采购订单单号
	 * @param errorCause 原因
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R notHandle(String purchaseOrderBid, String errorCause) throws Exception {
		//获取报错单信息 ，根据订单号
		List<TccOnlineAssembleError> assembleErrorList = new TccOnlineAssembleError().setPurchaseOrderBid(purchaseOrderBid).setStatus(1).queryList();
		//验证状态
		String errorMsg = handleBeforeCheck(purchaseOrderBid,assembleErrorList);
		if(checkUtil.isNotNullByObject(errorMsg)){
			return R.error(errorMsg);
		}
		/*
		if(checkUtil.isNullByObject(errorCause)){
			return R.error("请填写不处理的原因");
		}
		 */

		for(TccOnlineAssembleError item:assembleErrorList){
			item.setHandleStatus(TccOnlineAssembleErrorEnum.HandleStatus.NOT_DO.value);
			item.setErrorCause(errorCause);
			tccOnlineAssembleErrorMapper.update(item);
		}
		return R.ok();
	}

	/**
	 * 补发货
	 * @param purchaseOrderBid 采购订单单号
	 * @param logisticsMode 物流方式
	 * @param trackingNumber 物流单号
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R repairSend(String purchaseOrderBid,String logisticsMode,String trackingNumber) throws Exception {
		//获取报错单信息 ，根据订单号
		List<TccOnlineAssembleError> assembleErrorList = new TccOnlineAssembleError().setPurchaseOrderBid(purchaseOrderBid).setStatus(1).queryList();
		//验证状态
		String errorMsg = handleBeforeCheck(purchaseOrderBid,assembleErrorList);
		if(checkUtil.isNotNullByObject(errorMsg)){
			return R.error(errorMsg);
		}
		/*
		if(checkUtil.isNullByObject(errorCause)){
			return R.error("请填写不处理的原因");
		}
		 */

		//获取采购订单信息
		TcgPurchaseByOrder tcgPurchaseOrder = new TcgPurchaseByOrder().setBid(purchaseOrderBid).queryFirst();
		if(tcgPurchaseOrder==null || tcgPurchaseOrder.getId()==null ){
			return R.error("未查询到采购订单信息");
		}
		//采购订单子表
		List<TcgPurchaseByOrderSon> orderSonList = new TcgPurchaseByOrderSon().setPid(tcgPurchaseOrder.getId()).queryList();
		if(orderSonList==null || orderSonList.size()<=0 ){
			return R.error("未查询到采购订单信息");
		}

		//遍历，但正常就一条，一个订单号对应一条报错单
		for(TccOnlineAssembleError item:assembleErrorList){
			//修改报错单母表状态
			item.setHandleStatus(TccOnlineAssembleErrorEnum.HandleStatus.REPAIR_SEND.value);
			tccOnlineAssembleErrorMapper.update(item);
		}

		//获取子件信息
		List<TccOnlineAssembleErrorItem> sonList = new TccOnlineAssembleErrorItem()
				.addLeftJoin("TCC_OnlineAssembleError B ON B.Bid = A.Pbid")
				.where("B.PurchaseOrderBid = '"+purchaseOrderBid+"' AND B.Status = 1")
				.queryList();
		//生成采购入库单,回填入库单信息
		for(TccOnlineAssembleErrorItem sonItem:sonList){
			//根据子件id获取采购订单子表信息
			List<TcgPurchaseByOrderSon> orderSonListBySubCode = orderSonList.stream().filter(e->e.getSubCode().equals(sonItem.getSubCode())).collect(Collectors.toList());
			TcgPurchaseByOrderSon sonOrderInfo = orderSonListBySubCode.get(0);
			//生成采购入库单
			R res = tcgOfflinePurchaseInStorageService.addTcgOfflinePurchaseInStorage(tcgPurchaseOrder,sonOrderInfo.getId()
					,trackingNumber,logisticsMode,1, TcgOfflinePurchaseInStorageEnum.AssembledStatus.ASSEMBLY_ERROR.value
					,sonItem.getSubAssembleLostNum());
			//回填入库单信息
			sonItem.setLogisticsMode(logisticsMode);
			sonItem.setTrackingNumber(trackingNumber);
			sonItem.setInStorageBid(res.get("data").toString());
			tccOnlineAssembleErrorItemMapper.update(sonItem);
		}

		return R.ok();
	}

	/**
	 * 采购赔偿
	 * @param purchaseOrderBid 采购订单单号
	 * @param expenseSettleReturnItemId 费用结算返还单子表id
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R purchasePay(String purchaseOrderBid,Long expenseSettleReturnItemId) throws Exception {
		//获取报错单信息 ，根据订单号
		List<TccOnlineAssembleError> assembleErrorList = new TccOnlineAssembleError().setPurchaseOrderBid(purchaseOrderBid).setStatus(1).queryList();
		//验证状态
		String errorMsg = handleBeforeCheck(purchaseOrderBid,assembleErrorList);
		if(checkUtil.isNotNullByObject(errorMsg)){
			return R.error(errorMsg);
		}

		//获取采购赔偿 总金额
		/*
		Map<String,Object> expenseSettleReturnInfo = new TcwExpenseSettleReturn()
				.addLeftJoin("(SELECT ISNULL(SUM(S.ReturnAmount),0) AS returnAmount,S.Pbid FROM TCW_ExpenseSettleReturnItem S GROUP BY S.Pbid) B ON B.Pbid = A.Bid")
				.addField("ISNULL(B.returnAmount,0) AS totalAmount")//总金额
				.setBid(expenseSettleReturnBid)
				.queryFirstMap();

		 */
		TcwExpenseSettleReturnItem tcwExpenseSettleReturnItem = new TcwExpenseSettleReturnItem()
				.setId(expenseSettleReturnItemId)
				.queryFirst();


		//遍历，但正常就一条，一个订单号对应一条报错单
		for(TccOnlineAssembleError item:assembleErrorList){
			//1、新增：费用结算返还单被调用详情表信息
			//先删除
			financeMapper.deleteExpenseSettleReturnUsedBySource(item.getId(), TcwExpenseSettleReturnUsedEnum.SourceType.TCC_OnlineAssembleError.value);
			//再新增：费用结算返还单被调用详情表信息
			TcwExpenseSettleReturnUsed expenseSettleReturnUsed = new TcwExpenseSettleReturnUsed();
			expenseSettleReturnUsed.setExpenseSettleReturnBid(tcwExpenseSettleReturnItem.getPbid());//费用结算返还单单号
			expenseSettleReturnUsed.setExpenseSettleReturnItemId(expenseSettleReturnItemId);//费用结算返还单子表id
			expenseSettleReturnUsed.setUsedSourceId(item.getId());//被调用数据id
			expenseSettleReturnUsed.setUsedSourceType(TcwExpenseSettleReturnUsedEnum.SourceType.TCC_OnlineAssembleError.value);//被调用单据类型（见枚举TcwExpenseSettleReturnUsedEnum）
			expenseSettleReturnUsed.setReturnAmountTotal(tcwExpenseSettleReturnItem.getReturnAmount());//返还总金额
			expenseSettleReturnUsed.setStatus(1);
			tcwExpenseSettleReturnUsedMapper.insert(expenseSettleReturnUsed);

			//2、修改报错单母表状态
			item.setHandleStatus(TccOnlineAssembleErrorEnum.HandleStatus.PURCHASE_PAY.value);
			tccOnlineAssembleErrorMapper.update(item);

		}
		return R.ok();
	}

	/**
	 * 采购退款
	 * @param purchaseOrderBid 采购订单单号
	 * @param backBid 线上采购退货单单号
	 */
	@Override
	@Transactional(timeout=120,propagation= Propagation.REQUIRES_NEW)
	public R purchaseBack(String purchaseOrderBid,String backBid) throws Exception {
		//获取报错单信息 ，根据订单号
		List<TccOnlineAssembleError> assembleErrorList = new TccOnlineAssembleError().setPurchaseOrderBid(purchaseOrderBid).setStatus(1).queryList();
		//验证状态
		String errorMsg = handleBeforeCheck(purchaseOrderBid,assembleErrorList);
		if(checkUtil.isNotNullByObject(errorMsg)){
			return R.error(errorMsg);
		}

		TccOnlinePurchaseReturn tccOnlinePurchaseReturn = new TccOnlinePurchaseReturn()
				.setBid(backBid)
				.queryFirst();

		//遍历，但正常就一条，一个订单号对应一条报错单
		for(TccOnlineAssembleError item:assembleErrorList){
			//1、新增：费用结算返还单被调用详情表信息
			//先删除
			storageMapper.deleteOnlinePurchaseReturnUsedBySource(item.getId(), TccOnlinePurchaseReturnUsedEnum.UsedSourceType.TCC_OnlineAssembleError.value);
			//再新增：费用结算返还单被调用详情表信息
			TccOnlinePurchaseReturnUsed usedEntity = new TccOnlinePurchaseReturnUsed();
			usedEntity.setPurchaseReturnBid(tccOnlinePurchaseReturn.getBid());//费用结算返还单单号
			usedEntity.setUsedSourceId(item.getId());//被调用数据id
			usedEntity.setUsedSourceType(TccOnlinePurchaseReturnUsedEnum.UsedSourceType.TCC_OnlineAssembleError.value);//被调用单据类型
			usedEntity.setReturnAmountTotal(tccOnlinePurchaseReturn.getRefundAmount());//返还总金额
			usedEntity.setStatus(1);
			tccOnlinePurchaseReturnUsedMapper.insert(usedEntity);

			//2、修改报错单母表状态
			item.setHandleStatus(TccOnlineAssembleErrorEnum.HandleStatus.PURCHASE_BACK.value);
			tccOnlineAssembleErrorMapper.update(item);

		}
		return R.ok();
	}



	//线上组装报错单删除，根据商品组装单id
	@Override
	public R delByAssembleBid(Long assembleId) throws Exception  {
		storageMapper.updateTccOnlineAssembleErrorStateByAssembleId(assembleId);
		return R.ok();
	}





}
